/**
 * 
 */

package com.wutianyi.nio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;

/**
 * @author wutianyi
 *         bytebuffer 有三个状态position, limit, capacity;
 */
public class CopyFileChannel {

	public void scatterAndGather(String file) throws FileNotFoundException {
		FileInputStream inputStream = new FileInputStream(file);
		FileChannel fc = inputStream.getChannel();
	}
	
	public void copyFileMemory(String src, String dest) throws IOException {

		long start = System.currentTimeMillis();
		RandomAccessFile outputStream = new RandomAccessFile(dest, "rw");
		FileChannel fcOut = outputStream.getChannel();
		FileInputStream inputStream = new FileInputStream(src);
		FileChannel fcIn = inputStream.getChannel();
		ByteBuffer buffer = ByteBuffer.allocate(2 * 1024 * 1024);
		int i = 0;
		int c = 0;
		while((i = fcIn.read(buffer)) != -1) {
			MappedByteBuffer mbb = fcOut.map(MapMode.READ_WRITE, c * 2 * 1024 * 1024, i);
			buffer.flip();
			mbb.put(buffer);
			c++;
			mbb.force();
			buffer.clear();
		}

		fcOut.close();
		fcIn.close();
		long end = System.currentTimeMillis();
		System.out.println(end - start);
	}

	public void memoryMap(String file) throws IOException {

		RandomAccessFile fin = new RandomAccessFile(file, "rw");
		FileChannel fc = fin.getChannel();
		MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());
		System.out.println(mbb.capacity());
		System.out.println(mbb.position());
		System.out.println(mbb.limit());
		if(mbb.isDirect()) {

			System.out.println("I am direct Buffer");
		}
		int i = mbb.position();
		while(i != mbb.limit()) {

			byte b = mbb.get();

			mbb.put(i, (byte)(b + 1));
			i = mbb.position();
		}
		mbb.force();
		fin.close();
	}

	public void copyFileNio(String src, String dest) throws IOException {

		long start = System.currentTimeMillis();
		FileInputStream fin = new FileInputStream(src);
		FileOutputStream fco = new FileOutputStream(dest);

		FileChannel fcIn = fin.getChannel();
		FileChannel fcOut = fco.getChannel();

		ByteBuffer buffer = ByteBuffer.allocate(1024);
		int i = 0;
		try {
			while((i = fcIn.read(buffer)) != -1) {
				buffer.flip();
				fcOut.write(buffer);
				buffer.clear();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}finally {
			fcIn.close();
			fcOut.close();
		}
		long end = System.currentTimeMillis();
		System.out.println(end - start);
	}

	public void copyFile(String src, String dest) throws IOException {

		long start = System.currentTimeMillis();
		FileInputStream inputStream = null;
		FileOutputStream fileOutputStream = null;
		try {
			inputStream = new FileInputStream(src);
			fileOutputStream = new FileOutputStream(dest);
			byte[] buffer = new byte[1024];
			int i = 0;
			while((i = inputStream.read(buffer)) != -1) {
				fileOutputStream.write(buffer, 0, i);
			}
		}catch(FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}catch(IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			inputStream.close();
			fileOutputStream.close();
		}
		long end = System.currentTimeMillis();
		System.out.println(end - start);
	}

	public void mymain() {

		try {
			FileInputStream fin = new FileInputStream("pom.xml");
			FileOutputStream fco = new FileOutputStream("pom_back.xml");
			FileChannel fcOut = fco.getChannel();
			FileChannel fc = fin.getChannel();
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			int i = 0;
			byte[] b = new byte[1024];
			while((i = fc.read(buffer)) != -1) {
				// 读之前需要调用的方法
				buffer.flip();
				// 都是以字节方式来进行读取
				// while(buffer.position() != buffer.limit()) {
				// System.out.println(buffer.getChar());
				// }
				// buffer.get(b, 0, i);
				fcOut.write(buffer);
				// System.out.println(new String(b));
				// System.out.println(i);
				// 写之前需要调用的方法
				buffer.clear();

			}
		}catch(FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}catch(IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws IOException {
		CopyFileChannel c = new CopyFileChannel();
//		c.copyFileNio("test.rmvb", "test_nio.rmvb");
//		c.copyFile("test.rmvb", "test_orginal.rmvb");
		c.copyFileMemory("test.rmvb", "test_memory.rmvb");
	}
}
